Application of Computer Vision on Road Data

 

Dataset & Problem Description



Self-driving cars need to be able to identify common entities on or alongside the road. The dataset "Udacity Self-Driving Car" on Roboflow provides 15000 images containing pedestrians, cars, traffic lights, bikers, etc and labels containing the coordinates for those objects. The objective of this vignettte is to train a computer vision model on the images in order to associate the labels with the correct objects. The vignette uses the YOLOv7 model to detect the different potential roadside objects and labels the objects along with the probability that the object is what it's labeled as.
 

Basic Setup



1. Clone YOLOv7
2. Load Pretrained Model
3. Download Dataset
4. Split test/train
5. Sample Labeling on a image

In [1]:
!pip install "torch<2.6" "torchvision<0.21"
import torch
print("CUDA available:", torch.cuda.is_available())
print("GPU name:", torch.cuda.get_device_name(0) if torch.cuda.is_available() else "No GPU")
Collecting torch<2.6 Downloading torch-2.5.1-cp312-cp312-manylinux1_x86_64.whl.metadata (28 kB) Collecting torchvision<0.21 Downloading torchvision-0.20.1-cp312-cp312-manylinux1_x86_64.whl.metadata (6.1 kB) Requirement already satisfied: filelock in /usr/local/lib/python3.12/dist-packages (from torch<2.6) (3.20.0) Requirement already satisfied: typing-extensions>=4.8.0 in /usr/local/lib/python3.12/dist-packages (from torch<2.6) (4.15.0) Requirement already satisfied: networkx in /usr/local/lib/python3.12/dist-packages (from torch<2.6) (3.6) Requirement already satisfied: jinja2 in /usr/local/lib/python3.12/dist-packages (from torch<2.6) (3.1.6) Requirement already satisfied: fsspec in /usr/local/lib/python3.12/dist-packages (from torch<2.6) (2025.3.0) Collecting nvidia-cuda-nvrtc-cu12==12.4.127 (from torch<2.6) Downloading nvidia_cuda_nvrtc_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl.metadata (1.5 kB) Collecting nvidia-cuda-runtime-cu12==12.4.127 (from torch<2.6) Downloading nvidia_cuda_runtime_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl.metadata (1.5 kB) Collecting nvidia-cuda-cupti-cu12==12.4.127 (from torch<2.6) Downloading nvidia_cuda_cupti_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl.metadata (1.6 kB) Collecting nvidia-cudnn-cu12==9.1.0.70 (from torch<2.6) Downloading nvidia_cudnn_cu12-9.1.0.70-py3-none-manylinux2014_x86_64.whl.metadata (1.6 kB) Collecting nvidia-cublas-cu12==12.4.5.8 (from torch<2.6) Downloading nvidia_cublas_cu12-12.4.5.8-py3-none-manylinux2014_x86_64.whl.metadata (1.5 kB) Collecting nvidia-cufft-cu12==11.2.1.3 (from torch<2.6) Downloading nvidia_cufft_cu12-11.2.1.3-py3-none-manylinux2014_x86_64.whl.metadata (1.5 kB) Collecting nvidia-curand-cu12==10.3.5.147 (from torch<2.6) Downloading nvidia_curand_cu12-10.3.5.147-py3-none-manylinux2014_x86_64.whl.metadata (1.5 kB) Collecting nvidia-cusolver-cu12==11.6.1.9 (from torch<2.6) Downloading nvidia_cusolver_cu12-11.6.1.9-py3-none-manylinux2014_x86_64.whl.metadata (1.6 kB) Collecting nvidia-cusparse-cu12==12.3.1.170 (from torch<2.6) Downloading nvidia_cusparse_cu12-12.3.1.170-py3-none-manylinux2014_x86_64.whl.metadata (1.6 kB) Collecting nvidia-nccl-cu12==2.21.5 (from torch<2.6) Downloading nvidia_nccl_cu12-2.21.5-py3-none-manylinux2014_x86_64.whl.metadata (1.8 kB) Collecting nvidia-nvtx-cu12==12.4.127 (from torch<2.6) Downloading nvidia_nvtx_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl.metadata (1.7 kB) Collecting nvidia-nvjitlink-cu12==12.4.127 (from torch<2.6) Downloading nvidia_nvjitlink_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl.metadata (1.5 kB) Collecting triton==3.1.0 (from torch<2.6) Downloading triton-3.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (1.3 kB) Requirement already satisfied: setuptools in /usr/local/lib/python3.12/dist-packages (from torch<2.6) (75.2.0) Collecting sympy==1.13.1 (from torch<2.6) Downloading sympy-1.13.1-py3-none-any.whl.metadata (12 kB) Requirement already satisfied: mpmath<1.4,>=1.1.0 in /usr/local/lib/python3.12/dist-packages (from sympy==1.13.1->torch<2.6) (1.3.0) Requirement already satisfied: numpy in /usr/local/lib/python3.12/dist-packages (from torchvision<0.21) (2.0.2) Requirement already satisfied: pillow!=8.3.*,>=5.3.0 in /usr/local/lib/python3.12/dist-packages (from torchvision<0.21) (11.3.0) Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.12/dist-packages (from jinja2->torch<2.6) (3.0.3) Downloading torch-2.5.1-cp312-cp312-manylinux1_x86_64.whl (906.4 MB)  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 906.4/906.4 MB 1.4 MB/s eta 0:00:00 [?25hDownloading nvidia_cublas_cu12-12.4.5.8-py3-none-manylinux2014_x86_64.whl (363.4 MB)  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 363.4/363.4 MB 3.8 MB/s eta 0:00:00 [?25hDownloading nvidia_cuda_cupti_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl (13.8 MB)  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 13.8/13.8 MB 63.6 MB/s eta 0:00:00 [?25hDownloading nvidia_cuda_nvrtc_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl (24.6 MB)  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 24.6/24.6 MB 58.4 MB/s eta 0:00:00 [?25hDownloading nvidia_cuda_runtime_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl (883 kB)  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 883.7/883.7 kB 24.6 MB/s eta 0:00:00 [?25hDownloading nvidia_cudnn_cu12-9.1.0.70-py3-none-manylinux2014_x86_64.whl (664.8 MB)  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 664.8/664.8 MB 2.7 MB/s eta 0:00:00 [?25hDownloading nvidia_cufft_cu12-11.2.1.3-py3-none-manylinux2014_x86_64.whl (211.5 MB)  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 211.5/211.5 MB 5.3 MB/s eta 0:00:00 [?25hDownloading nvidia_curand_cu12-10.3.5.147-py3-none-manylinux2014_x86_64.whl (56.3 MB)  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 56.3/56.3 MB 13.2 MB/s eta 0:00:00 [?25hDownloading nvidia_cusolver_cu12-11.6.1.9-py3-none-manylinux2014_x86_64.whl (127.9 MB)  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 127.9/127.9 MB 7.5 MB/s eta 0:00:00 [?25hDownloading nvidia_cusparse_cu12-12.3.1.170-py3-none-manylinux2014_x86_64.whl (207.5 MB)  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 207.5/207.5 MB 6.8 MB/s eta 0:00:00 [?25hDownloading nvidia_nccl_cu12-2.21.5-py3-none-manylinux2014_x86_64.whl (188.7 MB)  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 188.7/188.7 MB 6.0 MB/s eta 0:00:00 [?25hDownloading nvidia_nvjitlink_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl (21.1 MB)  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 21.1/21.1 MB 84.6 MB/s eta 0:00:00 [?25hDownloading nvidia_nvtx_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl (99 kB)  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 99.1/99.1 kB 9.8 MB/s eta 0:00:00 [?25hDownloading sympy-1.13.1-py3-none-any.whl (6.2 MB)  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6.2/6.2 MB 96.9 MB/s eta 0:00:00 [?25hDownloading triton-3.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (209.6 MB)  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 209.6/209.6 MB 5.8 MB/s eta 0:00:00 [?25hDownloading torchvision-0.20.1-cp312-cp312-manylinux1_x86_64.whl (7.2 MB)  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7.2/7.2 MB 102.7 MB/s eta 0:00:00 [?25hInstalling collected packages: triton, sympy, nvidia-nvtx-cu12, nvidia-nvjitlink-cu12, nvidia-nccl-cu12, nvidia-curand-cu12, nvidia-cufft-cu12, nvidia-cuda-runtime-cu12, nvidia-cuda-nvrtc-cu12, nvidia-cuda-cupti-cu12, nvidia-cublas-cu12, nvidia-cusparse-cu12, nvidia-cudnn-cu12, nvidia-cusolver-cu12, torch, torchvision Attempting uninstall: triton Found existing installation: triton 3.5.0 Uninstalling triton-3.5.0: Successfully uninstalled triton-3.5.0 Attempting uninstall: sympy Found existing installation: sympy 1.14.0 Uninstalling sympy-1.14.0: Successfully uninstalled sympy-1.14.0 Attempting uninstall: nvidia-nvtx-cu12 Found existing installation: nvidia-nvtx-cu12 12.6.77 Uninstalling nvidia-nvtx-cu12-12.6.77: Successfully uninstalled nvidia-nvtx-cu12-12.6.77 Attempting uninstall: nvidia-nvjitlink-cu12 Found existing installation: nvidia-nvjitlink-cu12 12.6.85 Uninstalling nvidia-nvjitlink-cu12-12.6.85: Successfully uninstalled nvidia-nvjitlink-cu12-12.6.85 Attempting uninstall: nvidia-nccl-cu12 Found existing installation: nvidia-nccl-cu12 2.27.5 Uninstalling nvidia-nccl-cu12-2.27.5: Successfully uninstalled nvidia-nccl-cu12-2.27.5 Attempting uninstall: nvidia-curand-cu12 Found existing installation: nvidia-curand-cu12 10.3.7.77 Uninstalling nvidia-curand-cu12-10.3.7.77: Successfully uninstalled nvidia-curand-cu12-10.3.7.77 Attempting uninstall: nvidia-cufft-cu12 Found existing installation: nvidia-cufft-cu12 11.3.0.4 Uninstalling nvidia-cufft-cu12-11.3.0.4: Successfully uninstalled nvidia-cufft-cu12-11.3.0.4 Attempting uninstall: nvidia-cuda-runtime-cu12 Found existing installation: nvidia-cuda-runtime-cu12 12.6.77 Uninstalling nvidia-cuda-runtime-cu12-12.6.77: Successfully uninstalled nvidia-cuda-runtime-cu12-12.6.77 Attempting uninstall: nvidia-cuda-nvrtc-cu12 Found existing installation: nvidia-cuda-nvrtc-cu12 12.6.77 Uninstalling nvidia-cuda-nvrtc-cu12-12.6.77: Successfully uninstalled nvidia-cuda-nvrtc-cu12-12.6.77 Attempting uninstall: nvidia-cuda-cupti-cu12 Found existing installation: nvidia-cuda-cupti-cu12 12.6.80 Uninstalling nvidia-cuda-cupti-cu12-12.6.80: Successfully uninstalled nvidia-cuda-cupti-cu12-12.6.80 Attempting uninstall: nvidia-cublas-cu12 Found existing installation: nvidia-cublas-cu12 12.6.4.1 Uninstalling nvidia-cublas-cu12-12.6.4.1: Successfully uninstalled nvidia-cublas-cu12-12.6.4.1 Attempting uninstall: nvidia-cusparse-cu12 Found existing installation: nvidia-cusparse-cu12 12.5.4.2 Uninstalling nvidia-cusparse-cu12-12.5.4.2: Successfully uninstalled nvidia-cusparse-cu12-12.5.4.2 Attempting uninstall: nvidia-cudnn-cu12 Found existing installation: nvidia-cudnn-cu12 9.10.2.21 Uninstalling nvidia-cudnn-cu12-9.10.2.21: Successfully uninstalled nvidia-cudnn-cu12-9.10.2.21 Attempting uninstall: nvidia-cusolver-cu12 Found existing installation: nvidia-cusolver-cu12 11.7.1.2 Uninstalling nvidia-cusolver-cu12-11.7.1.2: Successfully uninstalled nvidia-cusolver-cu12-11.7.1.2 Attempting uninstall: torch Found existing installation: torch 2.9.0+cu126 Uninstalling torch-2.9.0+cu126: Successfully uninstalled torch-2.9.0+cu126 Attempting uninstall: torchvision Found existing installation: torchvision 0.24.0+cu126 Uninstalling torchvision-0.24.0+cu126: Successfully uninstalled torchvision-0.24.0+cu126 ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts. torchaudio 2.9.0+cu126 requires torch==2.9.0, but you have torch 2.5.1 which is incompatible. Successfully installed nvidia-cublas-cu12-12.4.5.8 nvidia-cuda-cupti-cu12-12.4.127 nvidia-cuda-nvrtc-cu12-12.4.127 nvidia-cuda-runtime-cu12-12.4.127 nvidia-cudnn-cu12-9.1.0.70 nvidia-cufft-cu12-11.2.1.3 nvidia-curand-cu12-10.3.5.147 nvidia-cusolver-cu12-11.6.1.9 nvidia-cusparse-cu12-12.3.1.170 nvidia-nccl-cu12-2.21.5 nvidia-nvjitlink-cu12-12.4.127 nvidia-nvtx-cu12-12.4.127 sympy-1.13.1 torch-2.5.1 torchvision-0.20.1 triton-3.1.0 CUDA available: True GPU name: Tesla T4
 

YOLO V7 Repository Clone

In [2]:
!nvidia-smi

# 1) Clone YOLOv7 repo
!git clone https://github.com/WongKinYiu/yolov7.git
%cd yolov7

# 2) Install requirements
!sed -i '/numpy/d' requirements.txt
!grep -i numpy requirements.txt

!pip install --upgrade pip
!pip install -r requirements.txt
Thu Dec 4 17:21:00 2025 +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 550.54.15 Driver Version: 550.54.15 CUDA Version: 12.4 | |-----------------------------------------+------------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+========================+======================| | 0 Tesla T4 Off | 00000000:00:04.0 Off | 0 | | N/A 35C P8 9W / 70W | 2MiB / 15360MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ +-----------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=========================================================================================| | No running processes found | +-----------------------------------------------------------------------------------------+ Cloning into 'yolov7'... remote: Enumerating objects: 1197, done. remote: Total 1197 (delta 0), reused 0 (delta 0), pack-reused 1197 (from 1) Receiving objects: 100% (1197/1197), 74.29 MiB | 19.69 MiB/s, done. Resolving deltas: 100% (511/511), done. /content/yolov7 Requirement already satisfied: pip in /usr/local/lib/python3.12/dist-packages (24.1.2) Collecting pip Downloading pip-25.3-py3-none-any.whl.metadata (4.7 kB) Downloading pip-25.3-py3-none-any.whl (1.8 MB)  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.8/1.8 MB 33.7 MB/s eta 0:00:00 [?25hInstalling collected packages: pip Attempting uninstall: pip Found existing installation: pip 24.1.2 Uninstalling pip-24.1.2: Successfully uninstalled pip-24.1.2 Successfully installed pip-25.3 Requirement already satisfied: matplotlib>=3.2.2 in /usr/local/lib/python3.12/dist-packages (from -r requirements.txt (line 4)) (3.10.0) Requirement already satisfied: opencv-python>=4.1.1 in /usr/local/lib/python3.12/dist-packages (from -r requirements.txt (line 5)) (4.12.0.88) Requirement already satisfied: Pillow>=7.1.2 in /usr/local/lib/python3.12/dist-packages (from -r requirements.txt (line 6)) (11.3.0) Requirement already satisfied: PyYAML>=5.3.1 in /usr/local/lib/python3.12/dist-packages (from -r requirements.txt (line 7)) (6.0.3) Requirement already satisfied: requests>=2.23.0 in /usr/local/lib/python3.12/dist-packages (from -r requirements.txt (line 8)) (2.32.4) Requirement already satisfied: scipy>=1.4.1 in /usr/local/lib/python3.12/dist-packages (from -r requirements.txt (line 9)) (1.16.3) Requirement already satisfied: torch!=1.12.0,>=1.7.0 in /usr/local/lib/python3.12/dist-packages (from -r requirements.txt (line 10)) (2.5.1) Requirement already satisfied: torchvision!=0.13.0,>=0.8.1 in /usr/local/lib/python3.12/dist-packages (from -r requirements.txt (line 11)) (0.20.1) Requirement already satisfied: tqdm>=4.41.0 in /usr/local/lib/python3.12/dist-packages (from -r requirements.txt (line 12)) (4.67.1) Collecting protobuf<4.21.3 (from -r requirements.txt (line 13)) Downloading protobuf-4.21.2-cp37-abi3-manylinux2014_x86_64.whl.metadata (540 bytes) Requirement already satisfied: tensorboard>=2.4.1 in /usr/local/lib/python3.12/dist-packages (from -r requirements.txt (line 16)) (2.19.0) Requirement already satisfied: pandas>=1.1.4 in /usr/local/lib/python3.12/dist-packages (from -r requirements.txt (line 20)) (2.2.2) Requirement already satisfied: seaborn>=0.11.0 in /usr/local/lib/python3.12/dist-packages (from -r requirements.txt (line 21)) (0.13.2) Requirement already satisfied: ipython in /usr/local/lib/python3.12/dist-packages (from -r requirements.txt (line 33)) (7.34.0) Requirement already satisfied: psutil in /usr/local/lib/python3.12/dist-packages (from -r requirements.txt (line 34)) (5.9.5) Collecting thop (from -r requirements.txt (line 35)) Downloading thop-0.1.1.post2209072238-py3-none-any.whl.metadata (2.7 kB) Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.12/dist-packages (from matplotlib>=3.2.2->-r requirements.txt (line 4)) (1.3.3) Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.12/dist-packages (from matplotlib>=3.2.2->-r requirements.txt (line 4)) (0.12.1) Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.12/dist-packages (from matplotlib>=3.2.2->-r requirements.txt (line 4)) (4.60.1) Requirement already satisfied: kiwisolver>=1.3.1 in /usr/local/lib/python3.12/dist-packages (from matplotlib>=3.2.2->-r requirements.txt (line 4)) (1.4.9) Requirement already satisfied: numpy>=1.23 in /usr/local/lib/python3.12/dist-packages (from matplotlib>=3.2.2->-r requirements.txt (line 4)) (2.0.2) Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.12/dist-packages (from matplotlib>=3.2.2->-r requirements.txt (line 4)) (25.0) Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.12/dist-packages (from matplotlib>=3.2.2->-r requirements.txt (line 4)) (3.2.5) Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.12/dist-packages (from matplotlib>=3.2.2->-r requirements.txt (line 4)) (2.9.0.post0) Requirement already satisfied: charset_normalizer<4,>=2 in /usr/local/lib/python3.12/dist-packages (from requests>=2.23.0->-r requirements.txt (line 8)) (3.4.4) Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.12/dist-packages (from requests>=2.23.0->-r requirements.txt (line 8)) (3.11) Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.12/dist-packages (from requests>=2.23.0->-r requirements.txt (line 8)) (2.5.0) Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.12/dist-packages (from requests>=2.23.0->-r requirements.txt (line 8)) (2025.11.12) Requirement already satisfied: filelock in /usr/local/lib/python3.12/dist-packages (from torch!=1.12.0,>=1.7.0->-r requirements.txt (line 10)) (3.20.0) Requirement already satisfied: typing-extensions>=4.8.0 in /usr/local/lib/python3.12/dist-packages (from torch!=1.12.0,>=1.7.0->-r requirements.txt (line 10)) (4.15.0) Requirement already satisfied: networkx in /usr/local/lib/python3.12/dist-packages (from torch!=1.12.0,>=1.7.0->-r requirements.txt (line 10)) (3.6) Requirement already satisfied: jinja2 in /usr/local/lib/python3.12/dist-packages (from torch!=1.12.0,>=1.7.0->-r requirements.txt (line 10)) (3.1.6) Requirement already satisfied: fsspec in /usr/local/lib/python3.12/dist-packages (from torch!=1.12.0,>=1.7.0->-r requirements.txt (line 10)) (2025.3.0) Requirement already satisfied: nvidia-cuda-nvrtc-cu12==12.4.127 in /usr/local/lib/python3.12/dist-packages (from torch!=1.12.0,>=1.7.0->-r requirements.txt (line 10)) (12.4.127) Requirement already satisfied: nvidia-cuda-runtime-cu12==12.4.127 in /usr/local/lib/python3.12/dist-packages (from torch!=1.12.0,>=1.7.0->-r requirements.txt (line 10)) (12.4.127) Requirement already satisfied: nvidia-cuda-cupti-cu12==12.4.127 in /usr/local/lib/python3.12/dist-packages (from torch!=1.12.0,>=1.7.0->-r requirements.txt (line 10)) (12.4.127) Requirement already satisfied: nvidia-cudnn-cu12==9.1.0.70 in /usr/local/lib/python3.12/dist-packages (from torch!=1.12.0,>=1.7.0->-r requirements.txt (line 10)) (9.1.0.70) Requirement already satisfied: nvidia-cublas-cu12==12.4.5.8 in /usr/local/lib/python3.12/dist-packages (from torch!=1.12.0,>=1.7.0->-r requirements.txt (line 10)) (12.4.5.8) Requirement already satisfied: nvidia-cufft-cu12==11.2.1.3 in /usr/local/lib/python3.12/dist-packages (from torch!=1.12.0,>=1.7.0->-r requirements.txt (line 10)) (11.2.1.3) Requirement already satisfied: nvidia-curand-cu12==10.3.5.147 in /usr/local/lib/python3.12/dist-packages (from torch!=1.12.0,>=1.7.0->-r requirements.txt (line 10)) (10.3.5.147) Requirement already satisfied: nvidia-cusolver-cu12==11.6.1.9 in /usr/local/lib/python3.12/dist-packages (from torch!=1.12.0,>=1.7.0->-r requirements.txt (line 10)) (11.6.1.9) Requirement already satisfied: nvidia-cusparse-cu12==12.3.1.170 in /usr/local/lib/python3.12/dist-packages (from torch!=1.12.0,>=1.7.0->-r requirements.txt (line 10)) (12.3.1.170) Requirement already satisfied: nvidia-nccl-cu12==2.21.5 in /usr/local/lib/python3.12/dist-packages (from torch!=1.12.0,>=1.7.0->-r requirements.txt (line 10)) (2.21.5) Requirement already satisfied: nvidia-nvtx-cu12==12.4.127 in /usr/local/lib/python3.12/dist-packages (from torch!=1.12.0,>=1.7.0->-r requirements.txt (line 10)) (12.4.127) Requirement already satisfied: nvidia-nvjitlink-cu12==12.4.127 in /usr/local/lib/python3.12/dist-packages (from torch!=1.12.0,>=1.7.0->-r requirements.txt (line 10)) (12.4.127) Requirement already satisfied: triton==3.1.0 in /usr/local/lib/python3.12/dist-packages (from torch!=1.12.0,>=1.7.0->-r requirements.txt (line 10)) (3.1.0) Requirement already satisfied: setuptools in /usr/local/lib/python3.12/dist-packages (from torch!=1.12.0,>=1.7.0->-r requirements.txt (line 10)) (75.2.0) Requirement already satisfied: sympy==1.13.1 in /usr/local/lib/python3.12/dist-packages (from torch!=1.12.0,>=1.7.0->-r requirements.txt (line 10)) (1.13.1) Requirement already satisfied: mpmath<1.4,>=1.1.0 in /usr/local/lib/python3.12/dist-packages (from sympy==1.13.1->torch!=1.12.0,>=1.7.0->-r requirements.txt (line 10)) (1.3.0) Requirement already satisfied: absl-py>=0.4 in /usr/local/lib/python3.12/dist-packages (from tensorboard>=2.4.1->-r requirements.txt (line 16)) (1.4.0) Requirement already satisfied: grpcio>=1.48.2 in /usr/local/lib/python3.12/dist-packages (from tensorboard>=2.4.1->-r requirements.txt (line 16)) (1.76.0) Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.12/dist-packages (from tensorboard>=2.4.1->-r requirements.txt (line 16)) (3.10) Requirement already satisfied: six>1.9 in /usr/local/lib/python3.12/dist-packages (from tensorboard>=2.4.1->-r requirements.txt (line 16)) (1.17.0) Requirement already satisfied: tensorboard-data-server<0.8.0,>=0.7.0 in /usr/local/lib/python3.12/dist-packages (from tensorboard>=2.4.1->-r requirements.txt (line 16)) (0.7.2) Requirement already satisfied: werkzeug>=1.0.1 in /usr/local/lib/python3.12/dist-packages (from tensorboard>=2.4.1->-r requirements.txt (line 16)) (3.1.3) Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.12/dist-packages (from pandas>=1.1.4->-r requirements.txt (line 20)) (2025.2) Requirement already satisfied: tzdata>=2022.7 in /usr/local/lib/python3.12/dist-packages (from pandas>=1.1.4->-r requirements.txt (line 20)) (2025.2) Collecting jedi>=0.16 (from ipython->-r requirements.txt (line 33)) Downloading jedi-0.19.2-py2.py3-none-any.whl.metadata (22 kB) Requirement already satisfied: decorator in /usr/local/lib/python3.12/dist-packages (from ipython->-r requirements.txt (line 33)) (4.4.2) Requirement already satisfied: pickleshare in /usr/local/lib/python3.12/dist-packages (from ipython->-r requirements.txt (line 33)) (0.7.5) Requirement already satisfied: traitlets>=4.2 in /usr/local/lib/python3.12/dist-packages (from ipython->-r requirements.txt (line 33)) (5.7.1) Requirement already satisfied: prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0 in /usr/local/lib/python3.12/dist-packages (from ipython->-r requirements.txt (line 33)) (3.0.52) Requirement already satisfied: pygments in /usr/local/lib/python3.12/dist-packages (from ipython->-r requirements.txt (line 33)) (2.19.2) Requirement already satisfied: backcall in /usr/local/lib/python3.12/dist-packages (from ipython->-r requirements.txt (line 33)) (0.2.0) Requirement already satisfied: matplotlib-inline in /usr/local/lib/python3.12/dist-packages (from ipython->-r requirements.txt (line 33)) (0.2.1) Requirement already satisfied: pexpect>4.3 in /usr/local/lib/python3.12/dist-packages (from ipython->-r requirements.txt (line 33)) (4.9.0) Requirement already satisfied: wcwidth in /usr/local/lib/python3.12/dist-packages (from prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0->ipython->-r requirements.txt (line 33)) (0.2.14) Requirement already satisfied: parso<0.9.0,>=0.8.4 in /usr/local/lib/python3.12/dist-packages (from jedi>=0.16->ipython->-r requirements.txt (line 33)) (0.8.5) Requirement already satisfied: ptyprocess>=0.5 in /usr/local/lib/python3.12/dist-packages (from pexpect>4.3->ipython->-r requirements.txt (line 33)) (0.7.0) Requirement already satisfied: MarkupSafe>=2.1.1 in /usr/local/lib/python3.12/dist-packages (from werkzeug>=1.0.1->tensorboard>=2.4.1->-r requirements.txt (line 16)) (3.0.3) Downloading protobuf-4.21.2-cp37-abi3-manylinux2014_x86_64.whl (407 kB) Downloading thop-0.1.1.post2209072238-py3-none-any.whl (15 kB) Downloading jedi-0.19.2-py2.py3-none-any.whl (1.6 MB)  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.6/1.6 MB 12.0 MB/s 0:00:00 [?25hInstalling collected packages: protobuf, jedi, thop  Attempting uninstall: protobuf  Found existing installation: protobuf 5.29.5  Uninstalling protobuf-5.29.5:  Successfully uninstalled protobuf-5.29.5  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3/3 [thop] ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts. google-cloud-datastore 2.21.0 requires protobuf!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. tensorflow-metadata 1.17.2 requires protobuf>=4.25.2; python_version >= "3.11", but you have protobuf 4.21.2 which is incompatible. google-cloud-bigtable 2.34.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. google-cloud-language 2.18.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. google-cloud-secret-manager 2.25.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. google-cloud-bigquery-connection 1.19.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. google-cloud-spanner 3.59.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. google-cloud-bigquery-storage 2.34.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. google-cloud-translate 3.23.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. google-ai-generativelanguage 0.6.15 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<6.0.0dev,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. google-cloud-firestore 2.21.0 requires protobuf!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0dev,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. google-cloud-dataproc 5.23.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. google-api-core 2.28.1 requires protobuf!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.19.5, but you have protobuf 4.21.2 which is incompatible. google-cloud-aiplatform 1.128.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. google-cloud-appengine-logging 1.7.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. grpc-google-iam-v1 0.14.3 requires protobuf!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. google-cloud-functions 1.21.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. googleapis-common-protos 1.72.0 requires protobuf!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. ydf 0.13.0 requires protobuf<7.0.0,>=5.29.1, but you have protobuf 4.21.2 which is incompatible. google-cloud-trace 1.17.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. tensorflow 2.19.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<6.0.0dev,>=3.20.3, but you have protobuf 4.21.2 which is incompatible. google-cloud-discoveryengine 0.13.12 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. grpcio-status 1.71.2 requires protobuf<6.0dev,>=5.26.1, but you have protobuf 4.21.2 which is incompatible. opentelemetry-proto 1.37.0 requires protobuf<7.0,>=5.0, but you have protobuf 4.21.2 which is incompatible. google-cloud-audit-log 0.4.0 requires protobuf!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. google-cloud-resource-manager 1.15.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. google-cloud-monitoring 2.28.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. google-cloud-logging 3.12.1 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. google-cloud-speech 2.34.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. Successfully installed jedi-0.19.2 protobuf-4.21.2 thop-0.1.1.post2209072238
 

Pre Trained Model YOLOv7



Base YOLOv7 weights

`
!wget https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7.pt
`


In [3]:
%cd /content/yolov7

# Download base YOLOv7 weights
# !wget -nc https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7.pt
!wget -nc https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7-tiny.pt

!ls -lh yolov7*.pt
/content/yolov7 --2025-12-04 17:21:20-- https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7-tiny.pt Resolving github.com (github.com)... 140.82.116.3 Connecting to github.com (github.com)|140.82.116.3|:443... connected. HTTP request sent, awaiting response... 302 Found Location: https://release-assets.githubusercontent.com/github-production-release-asset/511187726/ba7d01ee-125a-4134-8864-fa1abcbf94d5?sp=r&sv=2018-11-09&sr=b&spr=https&se=2025-12-04T18%3A17%3A57Z&rscd=attachment%3B+filename%3Dyolov7-tiny.pt&rsct=application%2Foctet-stream&skoid=96c2d410-5711-43a1-aedd-ab1947aa7ab0&sktid=398a6654-997b-47e9-b12b-9515b896b4de&skt=2025-12-04T17%3A17%3A04Z&ske=2025-12-04T18%3A17%3A57Z&sks=b&skv=2018-11-09&sig=gTqETvC%2B%2BboVZpsADyVgeSMPS0NzdtRESbF%2FCkYPCq0%3D&jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmVsZWFzZS1hc3NldHMuZ2l0aHVidXNlcmNvbnRlbnQuY29tIiwia2V5Ijoia2V5MSIsImV4cCI6MTc2NDg3MDY4MCwibmJmIjoxNzY0ODY4ODgwLCJwYXRoIjoicmVsZWFzZWFzc2V0cHJvZHVjdGlvbi5ibG9iLmNvcmUud2luZG93cy5uZXQifQ.ttVZTzjXKKv5aAJJ0FnvfdSGsb8i_BcSSHuoHp81EYQ&response-content-disposition=attachment%3B%20filename%3Dyolov7-tiny.pt&response-content-type=application%2Foctet-stream [following] --2025-12-04 17:21:20-- https://release-assets.githubusercontent.com/github-production-release-asset/511187726/ba7d01ee-125a-4134-8864-fa1abcbf94d5?sp=r&sv=2018-11-09&sr=b&spr=https&se=2025-12-04T18%3A17%3A57Z&rscd=attachment%3B+filename%3Dyolov7-tiny.pt&rsct=application%2Foctet-stream&skoid=96c2d410-5711-43a1-aedd-ab1947aa7ab0&sktid=398a6654-997b-47e9-b12b-9515b896b4de&skt=2025-12-04T17%3A17%3A04Z&ske=2025-12-04T18%3A17%3A57Z&sks=b&skv=2018-11-09&sig=gTqETvC%2B%2BboVZpsADyVgeSMPS0NzdtRESbF%2FCkYPCq0%3D&jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmVsZWFzZS1hc3NldHMuZ2l0aHVidXNlcmNvbnRlbnQuY29tIiwia2V5Ijoia2V5MSIsImV4cCI6MTc2NDg3MDY4MCwibmJmIjoxNzY0ODY4ODgwLCJwYXRoIjoicmVsZWFzZWFzc2V0cHJvZHVjdGlvbi5ibG9iLmNvcmUud2luZG93cy5uZXQifQ.ttVZTzjXKKv5aAJJ0FnvfdSGsb8i_BcSSHuoHp81EYQ&response-content-disposition=attachment%3B%20filename%3Dyolov7-tiny.pt&response-content-type=application%2Foctet-stream Resolving release-assets.githubusercontent.com (release-assets.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ... Connecting to release-assets.githubusercontent.com (release-assets.githubusercontent.com)|185.199.108.133|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 12639769 (12M) [application/octet-stream] Saving to: ‘yolov7-tiny.pt’ yolov7-tiny.pt 100%[===================>] 12.05M --.-KB/s in 0.1s 2025-12-04 17:21:20 (84.4 MB/s) - ‘yolov7-tiny.pt’ saved [12639769/12639769] -rw-r--r-- 1 root root 13M Jul 7 2022 yolov7-tiny.pt
 

Manual Dataset Download



https://public.roboflow.com/object-detection/self-driving-car
In [ ]:
# ===== Shenyi: Manual upload & extract YOLOv7 dataset =====

import os
from google.colab import files
import zipfile

# Upload the YOLOv7 dataset zip
uploaded = files.upload()

# Get file name
zip_name = next(iter(uploaded))
print("Uploaded zip:", zip_name)

# Extract to /content/data/yolov7
extract_dir = "/content/data/yolov7"
os.makedirs(extract_dir, exist_ok=True)

with zipfile.ZipFile(zip_name, "r") as zip_ref:
    zip_ref.extractall(extract_dir)

print("Extracted to:", extract_dir)

# List directory to verify st

Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
In [ ]:
# ===== Split export/ into train/ and valid/ (Shenyi) =====
from pathlib import Path
import random
import shutil
import os

export_root = Path("/content/data/yolov7/export")
images_dir = export_root / "images"
labels_dir = export_root / "labels"

print("Images dir exists:", images_dir.exists())
print("Labels dir exists:", labels_dir.exists())

# 1. collect images
image_files = sorted(list(images_dir.glob("*.jpg")) + list(images_dir.glob("*.png")))
print("Total images:", len(image_files))

# 2. split 80/20
random.seed(42)
random.shuffle(image_files)

train_ratio = 0.8
n_train = int(len(image_files) * train_ratio)

train_files = image_files[:n_train]
val_files   = image_files[n_train:]

print(f"Train images: {len(train_files)}")
print(f"Valid images: {len(val_files)}")

# 3. create folders
root = Path("/content/data/yolov7")
for split in ["train", "valid"]:
    for sub in ["images", "labels"]:
        (root / split / sub).mkdir(parents=True, exist_ok=True)

def copy_pair(img_path, split):
    """Copy image + label into train/ or valid/ folders."""
    dst_img = root / split / "images" / img_path.name
    shutil.copy2(img_path, dst_img)

    label_src = labels_dir / (img_path.stem + ".txt")
    if label_src.exists():
        dst_label = root / split / "labels" / label_src.name
        shutil.copy2(label_src, dst_label)

# 4. copy
for img in train_files:
    copy_pair(img, "train")

for img in val_files:
    copy_pair(img, "valid")

print("Done splitting dataset.")

# 5. check folders
!ls -R /content/data/yolov7
 

Auto Dataset Download



https://public.roboflow.com/object-detection/self-driving-car
In [4]:
%cd /content
!pip install roboflow

from google.colab import userdata
from roboflow import Roboflow

ROBOFLOW_API_KEY = "YHhbbD5tySkR1opc14ew"
if ROBOFLOW_API_KEY is None:
    raise ValueError("RoboflowApi is not set in Colab user data")

rf = Roboflow(api_key=ROBOFLOW_API_KEY)

project = rf.workspace("roboflow-gw7yv").project("self-driving-car")
version = project.version(3)

dataset = version.download("yolov7", location="data/yolov7")
print("Dataset location:", dataset.location)

/content Collecting roboflow Downloading roboflow-1.2.11-py3-none-any.whl.metadata (9.7 kB) Requirement already satisfied: certifi in /usr/local/lib/python3.12/dist-packages (from roboflow) (2025.11.12) Collecting idna==3.7 (from roboflow) Downloading idna-3.7-py3-none-any.whl.metadata (9.9 kB) Requirement already satisfied: cycler in /usr/local/lib/python3.12/dist-packages (from roboflow) (0.12.1) Requirement already satisfied: kiwisolver>=1.3.1 in /usr/local/lib/python3.12/dist-packages (from roboflow) (1.4.9) Requirement already satisfied: matplotlib in /usr/local/lib/python3.12/dist-packages (from roboflow) (3.10.0) Requirement already satisfied: numpy>=1.18.5 in /usr/local/lib/python3.12/dist-packages (from roboflow) (2.0.2) Collecting opencv-python-headless==4.10.0.84 (from roboflow) Downloading opencv_python_headless-4.10.0.84-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (20 kB) Requirement already satisfied: Pillow>=7.1.2 in /usr/local/lib/python3.12/dist-packages (from roboflow) (11.3.0) Collecting pi-heif<2 (from roboflow) Downloading pi_heif-1.1.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.metadata (6.5 kB) Collecting pillow-avif-plugin<2 (from roboflow) Downloading pillow_avif_plugin-1.5.2-cp312-cp312-manylinux_2_28_x86_64.whl.metadata (2.1 kB) Requirement already satisfied: python-dateutil in /usr/local/lib/python3.12/dist-packages (from roboflow) (2.9.0.post0) Requirement already satisfied: python-dotenv in /usr/local/lib/python3.12/dist-packages (from roboflow) (1.2.1) Requirement already satisfied: requests in /usr/local/lib/python3.12/dist-packages (from roboflow) (2.32.4) Requirement already satisfied: six in /usr/local/lib/python3.12/dist-packages (from roboflow) (1.17.0) Requirement already satisfied: urllib3>=1.26.6 in /usr/local/lib/python3.12/dist-packages (from roboflow) (2.5.0) Requirement already satisfied: tqdm>=4.41.0 in /usr/local/lib/python3.12/dist-packages (from roboflow) (4.67.1) Requirement already satisfied: PyYAML>=5.3.1 in /usr/local/lib/python3.12/dist-packages (from roboflow) (6.0.3) Requirement already satisfied: requests-toolbelt in /usr/local/lib/python3.12/dist-packages (from roboflow) (1.0.0) Collecting filetype (from roboflow) Downloading filetype-1.2.0-py2.py3-none-any.whl.metadata (6.5 kB) Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.12/dist-packages (from matplotlib->roboflow) (1.3.3) Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.12/dist-packages (from matplotlib->roboflow) (4.60.1) Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.12/dist-packages (from matplotlib->roboflow) (25.0) Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.12/dist-packages (from matplotlib->roboflow) (3.2.5) Requirement already satisfied: charset_normalizer<4,>=2 in /usr/local/lib/python3.12/dist-packages (from requests->roboflow) (3.4.4) Downloading roboflow-1.2.11-py3-none-any.whl (89 kB) Downloading idna-3.7-py3-none-any.whl (66 kB) Downloading opencv_python_headless-4.10.0.84-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (49.9 MB)  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 49.9/49.9 MB 51.0 MB/s 0:00:00 [?25hDownloading pi_heif-1.1.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (1.4 MB)  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 36.4 MB/s 0:00:00 [?25hDownloading pillow_avif_plugin-1.5.2-cp312-cp312-manylinux_2_28_x86_64.whl (4.2 MB)  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.2/4.2 MB 65.1 MB/s 0:00:00 [?25hDownloading filetype-1.2.0-py2.py3-none-any.whl (19 kB) Installing collected packages: pillow-avif-plugin, filetype, pi-heif, opencv-python-headless, idna, roboflow  Attempting uninstall: opencv-python-headless  Found existing installation: opencv-python-headless 4.12.0.88  Uninstalling opencv-python-headless-4.12.0.88:  Successfully uninstalled opencv-python-headless-4.12.0.88  Attempting uninstall: idna  Found existing installation: idna 3.11  Uninstalling idna-3.11:  Successfully uninstalled idna-3.11  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6/6 [roboflow] ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts. google-api-core 2.28.1 requires protobuf!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.19.5, but you have protobuf 4.21.2 which is incompatible. google-cloud-aiplatform 1.128.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. google-cloud-appengine-logging 1.7.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. google-cloud-functions 1.21.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. google-cloud-trace 1.17.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. tensorflow 2.19.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<6.0.0dev,>=3.20.3, but you have protobuf 4.21.2 which is incompatible. google-cloud-discoveryengine 0.13.12 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. google-cloud-resource-manager 1.15.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. google-cloud-monitoring 2.28.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. google-cloud-logging 3.12.1 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. google-cloud-speech 2.34.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2, but you have protobuf 4.21.2 which is incompatible. Successfully installed filetype-1.2.0 idna-3.7 opencv-python-headless-4.10.0.84 pi-heif-1.1.1 pillow-avif-plugin-1.5.2 roboflow-1.2.11 loading Roboflow workspace... loading Roboflow project...
Downloading Dataset Version Zip in data/yolov7 to yolov7pytorch:: 100%|██████████| 1147049/1147049 [00:17<00:00, 64387.79it/s]
Extracting Dataset Version Zip to data/yolov7 in yolov7pytorch:: 100%|██████████| 59606/59606 [00:09<00:00, 6175.65it/s]
Dataset location: /content/data/yolov7
 

Dataset (train/valid split)

In [5]:
from pathlib import Path
import random
import shutil

export_root = Path("data/yolov7/export")
images_dir = export_root / "images"
labels_dir = export_root / "labels"

print("Images dir exists:", images_dir.exists())
print("Labels dir exists:", labels_dir.exists())

image_files = sorted(list(images_dir.glob("*.jpg")) + list(images_dir.glob("*.png")))
print("Total images:", len(image_files))

random.seed(42)
random.shuffle(image_files)

train_ratio = 0.20
val_ratio = 0.05

n_train = int(len(image_files) * train_ratio)
n_val = int(len(image_files) * val_ratio)

train_files = image_files[:n_train]
val_files   = image_files[n_train : n_train + n_val]

print(f"Train images: {len(train_files)}")
print(f"Validation images: {len(val_files)}")

# data/yolov7/train|valid/{images,labels}
root = Path("data/yolov7")
for split in ["train", "valid"]:
    for sub in ["images", "labels"]:
        # Clear existing directories before recreating
        shutil.rmtree(root / split / sub, ignore_errors=True)
        (root / split / sub).mkdir(parents=True, exist_ok=True)

def copy_pair(img_path: Path, split: str):
    """Copy image and its label (if it exists) into train/ or valid/."""
    dst_img = root / split / "images" / img_path.name
    shutil.copy2(img_path, dst_img)

    label_src = labels_dir / (img_path.stem + ".txt")
    if label_src.exists():
        dst_label = root / split / "labels" / label_src.name
        shutil.copy2(label_src, dst_label)

for img in train_files:
    copy_pair(img, "train")

for img in val_files:
    copy_pair(img, "valid")

print("Done splitting dataset.")
Images dir exists: True Labels dir exists: True Total images: 29800 Train images: 5960 Validation images: 1490 Done splitting dataset.
In [6]:
%cd /content/yolov7

data_yaml = """
train: /content/data/yolov7/train/images
val: /content/data/yolov7/valid/images

nc: 11
names:
  - biker
  - car
  - pedestrian
  - trafficLight
  - trafficLight-Green
  - trafficLight-GreenLeft
  - trafficLight-Red
  - trafficLight-RedLeft
  - trafficLight-Yellow
  - trafficLight-YellowLeft
  - truck
"""

with open("self_driving_data.yaml", "w") as f:
    f.write(data_yaml)

print("Wrote config to /content/yolov7/self_driving_data.yaml")
/content/yolov7 Wrote config to /content/yolov7/self_driving_data.yaml
 

Sample Labeling

In [7]:
import yaml

data_config = yaml.safe_load(data_yaml)
names = data_config['names']
train_images_dir = Path("/content/data/yolov7/train/images")

print("Class names:", names)
Class names: ['biker', 'car', 'pedestrian', 'trafficLight', 'trafficLight-Green', 'trafficLight-GreenLeft', 'trafficLight-Red', 'trafficLight-RedLeft', 'trafficLight-Yellow', 'trafficLight-YellowLeft', 'truck']
In [8]:
import random
from PIL import Image
import matplotlib.pyplot as plt
import matplotlib.patches as patches

def load_image_and_labels(img_path: Path):
    label_path = Path(str(img_path).replace("images", "labels")).with_suffix(".txt")
    boxes = []
    if label_path.exists():
        with open(label_path, "r") as f:
            for line in f:
                parts = line.strip().split()
                cls_id = int(parts[0])
                x_c, y_c, w, h = map(float, parts[1:])
                boxes.append((cls_id, x_c, y_c, w, h))
    return Image.open(img_path).convert("RGB"), boxes

def plot_one_labeled_image(img_path: Path, class_names):
    img, boxes = load_image_and_labels(img_path)
    W, H = img.size

    fig, ax = plt.subplots(figsize=(6, 6))
    ax.imshow(img)

    for cls_id, x_c, y_c, w, h in boxes:
        x_c *= W; y_c *= H
        w *= W;  h *= H
        x0 = x_c - w / 2
        y0 = y_c - h / 2

        rect = patches.Rectangle(
            (x0, y0),
            w, h,
            linewidth=2,
            edgecolor="r",
            facecolor="none",
        )
        ax.add_patch(rect)

        label = class_names[cls_id]
        ax.text(
            x0, max(y0 - 5, 0),
            label,
            fontsize=8,
            bbox=dict(facecolor="white", alpha=0.7, edgecolor="none"),
        )

    ax.axis("off")
    plt.title("Sample labeled training image")
    plt.show()

train_images = list(train_images_dir.glob("*.jpg")) + list(train_images_dir.glob("*.png"))
print("Number of train images found:", len(train_images))

sample_img = random.choice(train_images)
print("Showing:", sample_img)
plot_one_labeled_image(sample_img, names)
Number of train images found: 5960 Showing: /content/data/yolov7/train/images/1478020599702483565_jpg.rf.b68489919ee5957bc8e23d19b6c671aa.jpg
Output
 
data/yolov7/data.yaml

`
names:
- biker
- car
- pedestrian
- trafficLight
- trafficLight-Green
- trafficLight-GreenLeft
- trafficLight-Red
- trafficLight-RedLeft
- trafficLight-Yellow
- trafficLight-YellowLeft
- truck
nc: 11
train: /content/data/yolov7/train/images
val: /content/data/yolov7/valid/images
`

 

Fine-tuning YOLOv7-Tiny on the Self-Driving Car Dataset


In [9]:
import os
os.environ["WANDB_DISABLED"] = "true"

%cd /content/yolov7
!grep -n "torch.load(weights, map_location=device)" train.py
!sed -i "s/torch.load(weights, map_location=device)/torch.load(weights, map_location=device, weights_only=False)/g" train.py
!grep -n "torch.load(weights" train.py
/content/yolov7 71: run_id = torch.load(weights, map_location=device).get('wandb_id') if weights.endswith('.pt') and os.path.isfile(weights) else None 87: ckpt = torch.load(weights, map_location=device) # load checkpoint 71: run_id = torch.load(weights, map_location=device, weights_only=False).get('wandb_id') if weights.endswith('.pt') and os.path.isfile(weights) else None 87: ckpt = torch.load(weights, map_location=device, weights_only=False) # load checkpoint
 

Experiment 1


In [10]:
%cd /content/yolov7

EXP_NAME = "car-vision-yolov7-finetune"

!python train.py \
  --img 512 \
  --batch 4 \
  --epochs 5 \
  --data /content/yolov7/self_driving_data.yaml \
  --cfg cfg/training/yolov7-tiny.yaml \
  --weights yolov7-tiny.pt \
  --name {EXP_NAME}
/content/yolov7 2025-12-04 17:24:54.202099: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:467] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered WARNING: All log messages before absl::InitializeLog() is called are written to STDERR E0000 00:00:1764869094.443639 4509 cuda_dnn.cc:8579] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered E0000 00:00:1764869094.510767 4509 cuda_blas.cc:1407] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered W0000 00:00:1764869095.023503 4509 computation_placer.cc:177] computation placer already registered. Please check linkage and avoid linking the same target more than once. W0000 00:00:1764869095.023552 4509 computation_placer.cc:177] computation placer already registered. Please check linkage and avoid linking the same target more than once. W0000 00:00:1764869095.023557 4509 computation_placer.cc:177] computation placer already registered. Please check linkage and avoid linking the same target more than once. W0000 00:00:1764869095.023561 4509 computation_placer.cc:177] computation placer already registered. Please check linkage and avoid linking the same target more than once. 2025-12-04 17:24:55.071495: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations. To enable the following instructions: AVX2 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags. YOLOR 🚀 v0.1-128-ga207844 torch 2.5.1+cu124 CUDA:0 (Tesla T4, 15095.0625MB) Namespace(weights='yolov7-tiny.pt', cfg='cfg/training/yolov7-tiny.yaml', data='/content/yolov7/self_driving_data.yaml', hyp='data/hyp.scratch.p5.yaml', epochs=5, batch_size=4, img_size=[512, 512], rect=False, resume=False, nosave=False, notest=False, noautoanchor=False, evolve=False, bucket='', cache_images=False, image_weights=False, device='', multi_scale=False, single_cls=False, adam=False, sync_bn=False, local_rank=-1, workers=8, project='runs/train', entity=None, name='car-vision-yolov7-finetune', exist_ok=False, quad=False, linear_lr=False, label_smoothing=0.0, upload_dataset=False, bbox_interval=-1, save_period=-1, artifact_alias='latest', freeze=[0], v5_metric=False, world_size=1, global_rank=-1, save_dir='runs/train/car-vision-yolov7-finetune', total_batch_size=4) tensorboard: Start with 'tensorboard --logdir runs/train', view at http://localhost:6006/ hyperparameters: lr0=0.01, lrf=0.1, momentum=0.937, weight_decay=0.0005, warmup_epochs=3.0, warmup_momentum=0.8, warmup_bias_lr=0.1, box=0.05, cls=0.3, cls_pw=1.0, obj=0.7, obj_pw=1.0, iou_t=0.2, anchor_t=4.0, fl_gamma=0.0, hsv_h=0.015, hsv_s=0.7, hsv_v=0.4, degrees=0.0, translate=0.2, scale=0.9, shear=0.0, perspective=0.0, flipud=0.0, fliplr=0.5, mosaic=1.0, mixup=0.15, copy_paste=0.0, paste_in=0.15, loss_ota=1 wandb: (1) Create a W&B account wandb: (2) Use an existing W&B account wandb: (3) Don't visualize my results wandb: Enter your choice: 3 wandb: You chose "Don't visualize my results" wandb: WARNING `resume` will be ignored since W&B syncing is set to `offline`. Starting a new run with run id k2otranj. wandb: Tracking run with wandb version 0.23.0 wandb: W&B syncing is set to `offline` in this directory. Run `wandb online` or set WANDB_MODE=online to enable cloud syncing. wandb: Run data is saved locally in /content/yolov7/wandb/offline-run-20251204_172517-k2otranj Overriding model.yaml nc=80 with nc=11 from n params module arguments 0 -1 1 928 models.common.Conv [3, 32, 3, 2, None, 1, LeakyReLU(negative_slope=0.1)] 1 -1 1 18560 models.common.Conv [32, 64, 3, 2, None, 1, LeakyReLU(negative_slope=0.1)] 2 -1 1 2112 models.common.Conv [64, 32, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 3 -2 1 2112 models.common.Conv [64, 32, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 4 -1 1 9280 models.common.Conv [32, 32, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)] 5 -1 1 9280 models.common.Conv [32, 32, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)] 6 [-1, -2, -3, -4] 1 0 models.common.Concat [1] 7 -1 1 8320 models.common.Conv [128, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 8 -1 1 0 models.common.MP [] 9 -1 1 4224 models.common.Conv [64, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 10 -2 1 4224 models.common.Conv [64, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 11 -1 1 36992 models.common.Conv [64, 64, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)] 12 -1 1 36992 models.common.Conv [64, 64, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)] 13 [-1, -2, -3, -4] 1 0 models.common.Concat [1] 14 -1 1 33024 models.common.Conv [256, 128, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 15 -1 1 0 models.common.MP [] 16 -1 1 16640 models.common.Conv [128, 128, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 17 -2 1 16640 models.common.Conv [128, 128, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 18 -1 1 147712 models.common.Conv [128, 128, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)] 19 -1 1 147712 models.common.Conv [128, 128, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)] 20 [-1, -2, -3, -4] 1 0 models.common.Concat [1] 21 -1 1 131584 models.common.Conv [512, 256, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 22 -1 1 0 models.common.MP [] 23 -1 1 66048 models.common.Conv [256, 256, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 24 -2 1 66048 models.common.Conv [256, 256, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 25 -1 1 590336 models.common.Conv [256, 256, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)] 26 -1 1 590336 models.common.Conv [256, 256, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)] 27 [-1, -2, -3, -4] 1 0 models.common.Concat [1] 28 -1 1 525312 models.common.Conv [1024, 512, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 29 -1 1 131584 models.common.Conv [512, 256, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 30 -2 1 131584 models.common.Conv [512, 256, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 31 -1 1 0 models.common.SP [5] 32 -2 1 0 models.common.SP [9] 33 -3 1 0 models.common.SP [13] 34 [-1, -2, -3, -4] 1 0 models.common.Concat [1] 35 -1 1 262656 models.common.Conv [1024, 256, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 36 [-1, -7] 1 0 models.common.Concat [1] 37 -1 1 131584 models.common.Conv [512, 256, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 38 -1 1 33024 models.common.Conv [256, 128, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 39 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, 'nearest'] 40 21 1 33024 models.common.Conv [256, 128, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 41 [-1, -2] 1 0 models.common.Concat [1] 42 -1 1 16512 models.common.Conv [256, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 43 -2 1 16512 models.common.Conv [256, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 44 -1 1 36992 models.common.Conv [64, 64, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)] 45 -1 1 36992 models.common.Conv [64, 64, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)] 46 [-1, -2, -3, -4] 1 0 models.common.Concat [1] 47 -1 1 33024 models.common.Conv [256, 128, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 48 -1 1 8320 models.common.Conv [128, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 49 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, 'nearest'] 50 14 1 8320 models.common.Conv [128, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 51 [-1, -2] 1 0 models.common.Concat [1] 52 -1 1 4160 models.common.Conv [128, 32, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 53 -2 1 4160 models.common.Conv [128, 32, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 54 -1 1 9280 models.common.Conv [32, 32, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)] 55 -1 1 9280 models.common.Conv [32, 32, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)] 56 [-1, -2, -3, -4] 1 0 models.common.Concat [1] 57 -1 1 8320 models.common.Conv [128, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 58 -1 1 73984 models.common.Conv [64, 128, 3, 2, None, 1, LeakyReLU(negative_slope=0.1)] 59 [-1, 47] 1 0 models.common.Concat [1] 60 -1 1 16512 models.common.Conv [256, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 61 -2 1 16512 models.common.Conv [256, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 62 -1 1 36992 models.common.Conv [64, 64, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)] 63 -1 1 36992 models.common.Conv [64, 64, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)] 64 [-1, -2, -3, -4] 1 0 models.common.Concat [1] 65 -1 1 33024 models.common.Conv [256, 128, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 66 -1 1 295424 models.common.Conv [128, 256, 3, 2, None, 1, LeakyReLU(negative_slope=0.1)] 67 [-1, 37] 1 0 models.common.Concat [1] 68 -1 1 65792 models.common.Conv [512, 128, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 69 -2 1 65792 models.common.Conv [512, 128, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 70 -1 1 147712 models.common.Conv [128, 128, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)] 71 -1 1 147712 models.common.Conv [128, 128, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)] 72 [-1, -2, -3, -4] 1 0 models.common.Concat [1] 73 -1 1 131584 models.common.Conv [512, 256, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)] 74 57 1 73984 models.common.Conv [64, 128, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)] 75 65 1 295424 models.common.Conv [128, 256, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)] 76 73 1 1180672 models.common.Conv [256, 512, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)] 77 [74, 75, 76] 1 44192 models.yolo.IDetect [11, [[10, 13, 16, 30, 33, 23], [30, 61, 62, 45, 59, 119], [116, 90, 156, 198, 373, 326]], [128, 256, 512]] /usr/local/lib/python3.12/dist-packages/torch/functional.py:534: UserWarning: torch.meshgrid: in an upcoming release, it will be required to pass the indexing argument. (Triggered internally at ../aten/src/ATen/native/TensorShape.cpp:3595.) return _VF.meshgrid(tensors, **kwargs) # type: ignore[attr-defined] Model Summary: 263 layers, 6042048 parameters, 6042048 gradients, 13.3 GFLOPS Transferred 330/344 items from yolov7-tiny.pt Scaled weight_decay = 0.0005 Optimizer groups: 58 .bias, 58 conv.weight, 61 other train: Scanning '/content/data/yolov7/train/labels' images and labels... 595 found, 0 missing, 1 empty, 0 corrupted: 10% 595/5960 [00:00<00:01, 3001.95it/s]train: WARNING: Ignoring corrupted image and/or label /content/data/yolov7/train/images/1478021875081281646_jpg.rf.e9552980cf8c6fef4aa02cb84c6364f5.jpg: duplicate labels train: Scanning '/content/data/yolov7/train/labels' images and labels... 3622 found, 0 missing, 522 empty, 1 corrupted: 61% 3622/5960 [00:01<00:00, 3477.17it/s]train: WARNING: Ignoring corrupted image and/or label /content/data/yolov7/train/images/1478898145212453716_jpg.rf.6a92d7d7dd523160c990c4e4375bcea9.jpg: duplicate labels train: Scanning '/content/data/yolov7/train/labels' images and labels... 5960 found, 0 missing, 702 empty, 2 corrupted: 100% 5960/5960 [00:01<00:00, 3399.58it/s] train: New cache created: /content/data/yolov7/train/labels.cache val: Scanning '/content/data/yolov7/valid/labels' images and labels... 783 found, 0 missing, 133 empty, 0 corrupted: 53% 783/1490 [00:00<00:00, 1954.74it/s]val: WARNING: Ignoring corrupted image and/or label /content/data/yolov7/valid/images/1478897760163798179_jpg.rf.98623be50b02ff17d58f89fddf7a0c6c.jpg: duplicate labels val: Scanning '/content/data/yolov7/valid/labels' images and labels... 1490 found, 0 missing, 175 empty, 1 corrupted: 100% 1490/1490 [00:00<00:00, 2170.60it/s] val: New cache created: /content/data/yolov7/valid/labels.cache autoanchor: Analyzing anchors... anchors/target = 4.97, Best Possible Recall (BPR) = 0.9996 /content/yolov7/train.py:299: FutureWarning: `torch.cuda.amp.GradScaler(args...)` is deprecated. Please use `torch.amp.GradScaler('cuda', args...)` instead. scaler = amp.GradScaler(enabled=cuda) Image sizes 512 train, 512 test Using 2 dataloader workers Logging results to runs/train/car-vision-yolov7-finetune Starting training for 5 epochs... Epoch gpu_mem box obj cls total labels img_size 0% 0/1490 [00:00<?, ?it/s]/content/yolov7/train.py:360: FutureWarning: `torch.cuda.amp.autocast(args...)` is deprecated. Please use `torch.amp.autocast('cuda', args...)` instead. with amp.autocast(enabled=cuda): 0/4 0.218G 0.06749 0.009839 0.01568 0.09301 28 512: 100% 1490/1490 [03:53<00:00, 6.39it/s] Class Images Labels P R mAP@.5 mAP@.5:.95: 100% 187/187 [00:18<00:00, 10.30it/s] all 1489 9727 0.468 0.186 0.119 0.0413 Epoch gpu_mem box obj cls total labels img_size 1/4 0.562G 0.05175 0.009165 0.009161 0.07007 23 512: 100% 1490/1490 [03:31<00:00, 7.04it/s] Class Images Labels P R mAP@.5 mAP@.5:.95: 100% 187/187 [00:17<00:00, 10.81it/s] all 1489 9727 0.639 0.222 0.194 0.0799 Epoch gpu_mem box obj cls total labels img_size 2/4 0.661G 0.04772 0.008976 0.007336 0.06403 86 512: 100% 1490/1490 [03:26<00:00, 7.22it/s] Class Images Labels P R mAP@.5 mAP@.5:.95: 100% 187/187 [00:16<00:00, 11.23it/s] all 1489 9727 0.411 0.24 0.21 0.0866 Epoch gpu_mem box obj cls total labels img_size 3/4 0.661G 0.04437 0.008801 0.00622 0.05939 5 512: 100% 1490/1490 [03:22<00:00, 7.36it/s] Class Images Labels P R mAP@.5 mAP@.5:.95: 100% 187/187 [00:16<00:00, 11.56it/s] all 1489 9727 0.459 0.306 0.251 0.11 Epoch gpu_mem box obj cls total labels img_size 4/4 0.661G 0.04324 0.008666 0.005979 0.05788 7 512: 100% 1490/1490 [03:22<00:00, 7.35it/s] Class Images Labels P R mAP@.5 mAP@.5:.95: 100% 187/187 [00:18<00:00, 9.95it/s] all 1489 9727 0.519 0.281 0.271 0.121 biker 1489 220 0 0 0.0463 0.0151 car 1489 6399 0.645 0.756 0.757 0.409 pedestrian 1489 1063 0.469 0.315 0.295 0.101 trafficLight 1489 256 0.187 0.152 0.152 0.0605 trafficLight-Green 1489 521 0.523 0.43 0.343 0.108 trafficLight-GreenLeft 1489 29 1 0 0.0103 0.00478 trafficLight-Red 1489 666 0.435 0.548 0.45 0.158 trafficLight-RedLeft 1489 166 0.474 0.00602 0.141 0.0627 trafficLight-Yellow 1489 28 1 0 0.00734 0.00273 truck 1489 379 0.461 0.599 0.51 0.285 5 epochs completed in 0.321 hours. /content/yolov7/utils/general.py:802: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature. x = torch.load(f, map_location=torch.device('cpu')) Optimizer stripped from runs/train/car-vision-yolov7-finetune/weights/last.pt, 12.3MB Optimizer stripped from runs/train/car-vision-yolov7-finetune/weights/best.pt, 12.3MB Images sizes do not match. This will causes images to be display incorrectly in the UI. wandb: wandb: Run history: wandb: metrics/mAP_0.5 ▁▄▅▇█ wandb: metrics/mAP_0.5:0.95 ▁▄▅▇█ wandb: metrics/precision ▃█▁▂▄ wandb: metrics/recall ▁▃▄█▇ wandb: train/box_loss █▃▂▁▁ wandb: train/cls_loss █▃▂▁▁ wandb: train/obj_loss █▄▃▂▁ wandb: val/box_loss █▃▃▂▁ wandb: val/cls_loss █▄▃▂▁ wandb: val/obj_loss ▁█▆▇█ wandb: +3 ... wandb: wandb: Run summary: wandb: metrics/mAP_0.5 0.27121 wandb: metrics/mAP_0.5:0.95 0.12064 wandb: metrics/precision 0.51941 wandb: metrics/recall 0.28062 wandb: train/box_loss 0.04324 wandb: train/cls_loss 0.00598 wandb: train/obj_loss 0.00867 wandb: val/box_loss 0.06693 wandb: val/cls_loss 0.01501 wandb: val/obj_loss 0.02313 wandb: +3 ... wandb: wandb: You can sync this run to the cloud by running: wandb: wandb sync /content/yolov7/wandb/offline-run-20251204_172517-k2otranj wandb: Find logs at: ./wandb/offline-run-20251204_172517-k2otranj/logs
 

Experiment 1 Evaluation


 
evaluate the model
* Show metrics (mAP, precision/recall) if available.
* Show loss curve or final results.

run inference + visualise predictions
* Run the trained model on a few test images.
* Display images with predicted boxes.
In [11]:
# evaluate the model
#   Show metrics (mAP, precision/recall) if available.
#   Show loss curve or final results.

import os
from IPython.display import Image, display

results_dir = os.path.join('/content/yolov7/runs/train', EXP_NAME)

# Display training metrics from results.txt
results_file = os.path.join(results_dir, 'results.txt')
if os.path.exists(results_file):
    print(f"\n--- Training Metrics ({EXP_NAME}) ---")
    with open(results_file, 'r') as f:
        print(f.read())
else:
    print(f"Results file not found: {results_file}")

# Display results plot (loss curves, mAP, etc.)
results_plot = os.path.join(results_dir, 'results.png')
if os.path.exists(results_plot):
    print(f"\n--- Training Results Plot ({EXP_NAME}) ---")
    display(Image(filename=results_plot, width=800))
else:
    print(f"Results plot not found: {results_plot}")

# Optionally, display confusion matrix and F1 curve if available
confusion_matrix_plot = os.path.join(results_dir, 'confusion_matrix.png')
if os.path.exists(confusion_matrix_plot):
    print(f"\n--- Confusion Matrix ({EXP_NAME}) ---")
    display(Image(filename=confusion_matrix_plot, width=800))

F1_curve_plot = os.path.join(results_dir, 'F1_curve.png')
if os.path.exists(F1_curve_plot):
    print(f"\n--- F1 Curve ({EXP_NAME}) ---")
    display(Image(filename=F1_curve_plot, width=800))
--- Training Metrics (car-vision-yolov7-finetune) --- 0/4 0.218G 0.06749 0.009839 0.01568 0.09301 28 512 0.4677 0.1856 0.1187 0.0413 0.08365 0.02043 0.02229 1/4 0.562G 0.05175 0.009165 0.009161 0.07007 23 512 0.6391 0.2219 0.1938 0.07993 0.0708 0.02323 0.01855 2/4 0.661G 0.04772 0.008976 0.007336 0.06403 86 512 0.4113 0.2403 0.2099 0.08657 0.07219 0.02227 0.01716 3/4 0.661G 0.04437 0.008801 0.00622 0.05939 5 512 0.4592 0.3059 0.2511 0.1105 0.06844 0.02288 0.01616 4/4 0.661G 0.04324 0.008666 0.005979 0.05788 7 512 0.5194 0.2806 0.2712 0.1206 0.06693 0.02313 0.01501 --- Training Results Plot (car-vision-yolov7-finetune) ---
Output
--- Confusion Matrix (car-vision-yolov7-finetune) ---
Output
--- F1 Curve (car-vision-yolov7-finetune) ---
Output
In [13]:
import cv2
import matplotlib.pyplot as plt
from pathlib import Path
import random

valid_img_dir = Path("/content/data/yolov7/valid/images")
valid_lbl_dir = Path("/content/data/yolov7/valid/labels")
pred_dir      = Path(f"runs/detect/{EXP_NAME}-results")

# Collect all validation images
val_images = list(valid_img_dir.glob("*.jpg")) + list(valid_img_dir.glob("*.png"))

def load_yolo_labels(label_path: Path, img_w: int, img_h: int):
    """
    Load YOLO-format labels (class x_center y_center width height, all normalized)
    and convert them to pixel coordinates (x1, y1, x2, y2).
    """
    boxes = []
    if not label_path.exists():
        return boxes

    with open(label_path, "r") as f:
        for line in f:
            parts = line.strip().split()
            if len(parts) != 5:
                continue
            cls, x_c, y_c, w, h = map(float, parts)
            x_c *= img_w
            y_c *= img_h
            w   *= img_w
            h   *= img_h

            x1 = int(x_c - w / 2)
            y1 = int(y_c - h / 2)
            x2 = int(x_c + w / 2)
            y2 = int(y_c + h / 2)

            boxes.append((int(cls), x1, y1, x2, y2))
    return boxes

def show_pred_vs_gt(img_path: Path):
    # Original image
    img = cv2.imread(str(img_path))
    if img is None:
        print(f"Could not read image: {img_path}")
        return
    img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    h, w, _ = img_rgb.shape

    # Ground-truth boxes
    label_path = valid_lbl_dir / f"{img_path.stem}.txt"
    gt_boxes = load_yolo_labels(label_path, w, h)

    # Draw GT boxes on a copy
    gt_img = img_rgb.copy()
    for cls_id, x1, y1, x2, y2 in gt_boxes:
        cv2.rectangle(gt_img, (x1, y1), (x2, y2), (0, 255, 0), 2)
        cv2.putText(gt_img, str(cls_id), (x1, y1 - 5),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)

    # Predicted image from detect.py (already has boxes drawn on it)
    pred_img_path = pred_dir / img_path.name
    if not pred_img_path.exists():
        print(f"No prediction image found for {img_path.name}, expected {pred_img_path}")
        return

    pred_img = cv2.imread(str(pred_img_path))
    pred_img = cv2.cvtColor(pred_img, cv2.COLOR_BGR2RGB)

    # Show side-by-side
    fig, axs = plt.subplots(1, 2, figsize=(12, 6))
    axs[0].imshow(gt_img)
    axs[0].set_title("Ground Truth")
    axs[0].axis("off")

    axs[1].imshow(pred_img)
    axs[1].set_title("Prediction")
    axs[1].axis("off")

    plt.tight_layout()
    plt.show()

# Show a few random samples
num_samples = min(5, len(val_images))
for img_path in random.sample(val_images, num_samples):
    print(f"\nImage: {img_path.name}")
    show_pred_vs_gt(img_path)
Image: 1478897914983365227_jpg.rf.YKObyzxbWy8Ea19X9B7y.jpg
Output
Image: 1478898368586708765_jpg.rf.sAk7i73HFL08ZBXJNk5T.jpg
Output
Image: 1478898657659698966_jpg.rf.4vdfFSo7zyusPxTe1xTr.jpg
Output
Image: 1478732799238372988_jpg.rf.4kkKlqztitrHm0VPBeE3.jpg
Output
Image: 1478899554585155627_jpg.rf.79d2ab4392f63d2acc8a0b8e98736f6a.jpg
Output
 

Experiment 2




(Epoch = 3, Image size 416)
In [ ]:
# experiment 2 (not running yet)
%cd /content/yolov7

EXP_NAME = "car-vision-img416-ep3"

!python train.py \
  --img 416 \
  --batch 4 \
  --epochs 3 \
  --data /content/yolov7/self_driving_data.yaml \
  --cfg cfg/training/yolov7-tiny.yaml \
  --weights yolov7-tiny.pt \
  --name {EXP_NAME}
 
###a brief summary (Shenyi):
baseline training - experiment1 (epoch = 1) metric
- mAP@0.5 - 0.189
- mAP@0.5:0.95 - 0.083
- Precision - 0.464
- Recall - 0.262

experiment2 (epoch = 3) metric
- mAP@0.5 - 0.273
- mAP@0.5:0.95 - 0.123
- Precision - 0.572
- Recall - 0.324

Increasing epochs from 1 to 3 significantly simporved all evalution metrics, the model learns better representations with more training iterations
 

Evaluation (Bahaar)

 
Across the two completed experiments, the trend is clear: increasing the number of training epochs substantially improves the model’s ability to detect objects in the self-driving dataset. The jump from 1 to 3 epochs produced noticeable gains across all metrics, particularly in precision and recall. This indicates that YOLOv7-Tiny is beginning to learn meaningful representations of the classes, but is still in the early stages of convergence.

Qualitative inspection of validation predictions also supports the numeric results. The model handles larger, more distinct objects (cars, trucks, cyclists) with growing confidence, while smaller objects such as traffic lights and pedestrians remain harder to localize consistently. This is expected given their small pixel footprint and the limited training time.

Overall, the experiments demonstrate the model’s potential but also confirm that much more training is required before it reaches stable performance.
 

Conclusion

 
These initial experiments show that YOLOv7-Tiny can begin to learn the structure of the dataset even with minimal training. The noticeable improvements from Experiment 1 to Experiment 2 illustrate how sensitive detection performance is to training duration. While the current accuracy levels are far from production-ready, the results provide a strong foundation for continued development.

Importantly, the steady upward trend in mAP, precision, and recall suggests that extending training to a realistic range (e.g., 50–100 epochs) would likely produce significant gains. The findings confirm that the chosen architecture is capable of adapting to the complexity of self-driving data, provided that it is trained sufficiently.
 

Limitations

 
1. Very short training duration.
Training for only 1–3 epochs severely limits the model’s ability to converge.

2. Small batch size (4).
Leads to noisy gradients and slower improvements.

3. Resolution fixed at 512×512.
Small objects still remain difficult to detect, and Experiment 3 (416×416) did not run due to path issues.

4. Potential class imbalance.
Traffic-light subclasses may have significantly fewer examples compared to cars/trucks.

5. Lack of detailed evaluation plots.
Loss curves, per-class AP, and confusion matrices would provide deeper insight but were not generated in this iteration.

6. No hyperparameter tuning.
Default settings were used; tuning could dramatically shift performance.